package com.jacky.demo.util;

import android.text.TextUtils;

import com.jacky.log.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by jacky on 2017-09-24.
 */
public final class MD5 {

    private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * 使用加盐的方式混淆加密
     *
     * @param string
     * @return 返回经过MD5算法加密后的字符串。如果string为null或空，则返回 null 值
     */
    public static String encryptSalt(String salt, String string) {
        StringBuilder builder = new StringBuilder();
        builder.append(salt).append(string).append(salt);
        return encrypt(builder.toString());
    }

    /**
     * 加密一次
     *
     * @param string
     * @return 返回经过MD5算法加密后的字符串。如果string为null或空，则返回 null 值
     */
    public static String encrypt(String string) {
        return encrypt(string.getBytes());
    }

    /**
     * 加密一次
     *
     * @param bytes
     * @return 返回经过MD5算法加密后的字符串。如果string为null或空，则返回 null 值
     */
    public static String encrypt(byte[] bytes) {
        if (bytes == null || bytes.length == 0) return "";

        byte[] b = encrypt_md5(bytes);
        return transferByte2String(b);
    }

    public static String encryptFile(File file) {
        if (file == null)
            return null;

        if (!file.exists())
            return null;

        String md5Str = null;
        FileInputStream fileInputStream = null;
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            fileInputStream = new FileInputStream(file);
            byte[] buffer = new byte[1024 * 32];
            int length;
            while ((length = fileInputStream.read(buffer)) != -1) {
                mdTemp.update(buffer, 0, length);
            }
            md5Str = transferByte2String(mdTemp.digest());
        } catch (Exception e) {
            Logger.e(e);
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    Logger.e(e);
                }
            }
        }
        return md5Str;
    }
    /**
     * 使用MD5算法加密
     *
     * @param bytes
     * @return
     */
    private static final byte[] encrypt_md5(byte[] bytes) {
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(bytes);
            return mdTemp.digest();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return bytes;
        }
    }

    /**
     * 将byte数组转化为十六进制的字符
     *
     * @param bytes
     * @return
     */
    private static final String transferByte2String(byte[] bytes) {
        int k = 0;
        int size = bytes == null ? 0 : bytes.length;
        char str[] = new char[size * 2];

        for (int i = 0; i < size; i++) {
            byte b = bytes[i];
            str[k++] = hexDigits[b >> 4 & 0xf];
            str[k++] = hexDigits[b & 0xf];
        }
        return new String(str);
    }

    /**
     * 获取字符串的哈希值
     *
     * @param string
     * @return
     */
    public static final String getHashcodeString(String string) {
        if (TextUtils.isEmpty(string)) return "";
        long hashcode = 0;
        int size = string.length();
        for (int i = 0; i < size; i++) {
            hashcode = 131 * hashcode + string.charAt(i);
        }
        return Long.toHexString(hashcode);
    }

    public static final String getShortMd5(String string) {
        String md5 = encrypt(string);
        int size = md5.length();
        if (size != 32) return "";

        char[] sm = new char[8];
        for (int i = 0; i < 8; i++) {
            sm[i] = md5.charAt(i * 4 + 1);
        }
        return new String(sm);
    }
}
